25.12.25 nextjs on-demand isr
마지막 수정일: 2025. 12. 24.
Problem
기존에는 time based로 작업됐음 25.01.30 ISR 적용 및 최적화 자세한 내용은 여기
60초마다 revalidate하게 설정했지만 생각보다 대기시간이 답답했고 너무 짧게 설정하자니 서버에 부담이라고 생각함
기존에도 on-demand 방식이 존재한다는 것은 알고 있었지만 보관 방법부터 trigger, scheduling까지 고려할 점들이 있었는데 이번에 aws 설정하면서 비용이 많이 내려가 바꾸기로 결정
해결 방법
고려해야할 점은 다음 3가지
- 어디에 저장할까(storage)
- 어떻게 감지할까(detection)
- 어떻게 ISR 서버를 re-build할까(revalidation)
Storage
일단 obsidian에서 지원하는 storage, plugin이어야한다.
먼저 plugin부터 살펴보면 크게 후보는 3가지
1번은 공식이지만 유료, 3번은 너무 좋지만 모바일에서는 문제가 있다는 내용이 많아서 기각
원래 사용하던 remotely save를 그대로 쓰기로 함
물론 remotely save에도 여러 storage를 지원하지만 가장 눈여겨 볼만한 거는 icloud와 s3
나는 icloud가 꽉 찼지만 icloud를 안 쓰는 사람이면 무료로 어느정도 많이 사용해 볼만할 듯
하지만 나는 s3로
Detection & Revalidation
S3를 사용했기 때문에 같은 AWS 서비스를 사용하는 게 경험상 훨씬 편하다고 생각
S3 lambda에 trigger, code 등 여러가지를 한 번에 할 수 있어서 detection과 revalidation을 한 번에 할 수 있었음
구조는 다음과 같이 구현
현재 블로그에 사용되는 kyungbin, programming, side proejct 이 3개를 trigger로 잡았음
코드는 간단하게 다음과 같이 배포
export const handler = async event => {
const records = event.Records || [];
for (const r of records) {
const key = decodeURIComponent(r.s3.object.key.replace(/\+/g, " "));
await fetch("https://myexampleurl.com/api", {
method: "POST",
headers: {
"content-type": "application/json",
},
body: JSON.stringify(key ? { key } : {}),
});
}
};
그리고 nextjs를 사용했기 때문에 같은 route로 api를 구현하여 배포했음
import { revalidatePath } from "next/cache";
import { NextRequest, NextResponse } from "next/server";
export async function POST(request: NextRequest) {
try {
const body = await request.json().catch(() => ({}));
const path = body.path;
if (path) {
revalidatePath(path);
} else {
revalidatePath("/dot", "layout");
}
return NextResponse.json({
revalidated: true,
now: Date.now(),
path: path || "all dot pages",
});
} catch (err) {
return NextResponse.json(
{
message: "Error revalidating",
error: err instanceof Error ? err.message : String(err),
},
{ status: 500 }
);
}
}
성과
거의 바로 배포되는 환경을 구현해낼 수 있었음